package org.gilgamesh.stool.core.time.custom;

import cn.hutool.core.date.*;
import cn.hutool.core.date.format.FastDateFormat;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * super-tool自定义时间类型
 *
 * @author Gilgamesh
 * @date 2021-08-19
 **/
public class CustomDate extends DateTime {

    public CustomDate(long timeStamp) {
        super(timeStamp);
    }

    public CustomDate() {
        super();
    }

    public CustomDate(Date date) {
        super(date);
    }

    /**
     * 相当于new Date();
     *
     * @author Gilgamesh
     * @since 2021-08-19
     **/
    public static CustomDate date() {
        return new CustomDate();
    }

    /**
     * 创建CustomDate
     **/
    public static CustomDate date(long timeStamp) {
        return new CustomDate(timeStamp);
    }

    /**
     * 创建CustomDate
     **/
    public static CustomDate date(Date date) {
        return new CustomDate(date);
    }

    /**
     * 昨天
     **/
    public CustomDate yesterday() {
        return new CustomDate(DateUtil.yesterday().getTime());
    }

    /**
     * 某一天的开始
     **/
    public CustomDate beginOfDay() {
        long time = DateUtil.beginOfDay(this).getTime();
        return new CustomDate(time);
    }

    /**
     * 一天的结束
     **/
    public CustomDate endOfDay() {
        long time = DateUtil.endOfDay(this).getTime();
        return new CustomDate(time);
    }

    /**
     * 时间格式化
     * 返回ISO8601日期时间格式，精确到毫秒 {@link FastDateFormat}：yyyy-MM-dd HH:mm:ss,SSS
     */
    public String format_ISO8601() {
        return DateUtil.format(this, DatePattern.ISO8601_FORMAT);
    }

    /**
     * 时间格式化
     * 标准日期格式 {@link FastDateFormat}：yyyy年MM月dd日HH时mm分ss秒
     */
    public String format_CHINESE() {
        return format(DatePattern.CHINESE_DATE_TIME_FORMAT);
    }

    /**
     * 时间格式化
     * 返回ISO8601日期时间格式，精确到毫秒 {@link FastDateFormat}：yyyy-MM-dd HH:mm:ss,SSS
     */
    public String format() {
        return format(DatePattern.ISO8601_FORMAT);
    }

    /**
     * 时间格式化
     **/
    public String format(FastDateFormat pattern) {
        return DateUtil.format(this, pattern);
    }

    /**
     * 获取指定日期偏移指定时间后的时间，生成的偏移日期不影响原日期
     *
     * @param field  偏移的粒度大小（小时、天、月等）{@link DateField}
     * @param offset 偏移量，正数为向后偏移，负数为向前偏移
     * @return 偏移后的日期
     */
    public CustomDate offset(DateField field, int offset) {
        DateTime dateTime = DateUtil.offset(this, field, offset);
        return date(dateTime);
    }

    /**
     * 当前时间
     *
     * @param timeZone 时区
     * @since 2021-08-23
     */
    public CustomDate(TimeZone timeZone) {
        super(timeZone);
    }

    /**
     * 调整日期和时间<br>
     * 返回调整后的新CustomDate，不影响原对象
     *
     * @param datePart 调整的部分 {@link DateField}
     * @param offset   偏移量，正数为向后偏移，负数为向前偏移
     * @return 如果此对象为可变对象，返回自身，否则返回新对象
     * @since 2021-08-23
     */
    @Override
    public CustomDate offsetNew(DateField datePart, int offset) {
        return date(super.offsetNew(datePart, offset));
    }

    /**
     * 设置日期的某个部分<br>
     * 如果此对象为可变对象，返回自身，否则返回新对象，设置是否可变对象见{@link #setMutable(boolean)}
     *
     * @param field 表示日期的哪个部分的枚举 {@link DateField}
     * @param value 值
     * @return this
     */
    @Override
    public CustomDate setField(DateField field, int value) {
        return date(super.setField(field, value));
    }

    /**
     * 设置日期的某个部分<br>
     * 如果此对象为可变对象，返回自身，否则返回新对象，设置是否可变对象见{@link #setMutable(boolean)}
     *
     * @param field 表示日期的哪个部分的int值 {@link Calendar}
     * @param value 值
     * @return this
     */
    @Override
    public CustomDate setField(int field, int value) {
        return date(super.setField(field, value));
    }

    /**
     * 设置对象是否可变 如果为不可变对象，以下方法将返回新方法：
     * <ul>
     * <li>{@link CustomDate#offset(DateField, int)}</li>
     * <li>{@link CustomDate#setField(DateField, int)}</li>
     * <li>{@link CustomDate#setField(int, int)}</li>
     * </ul>
     * 如果为不可变对象，{@link CustomDate#setTime(long)}将抛出异常
     *
     * @param mutable 是否可变
     * @return this
     */
    @Override
    public CustomDate setMutable(boolean mutable) {
        return date(super.setMutable(mutable));
    }

    /**
     * 设置一周的第一天<br>
     * JDK的Calendar中默认一周的第一天是周日，Hutool中将此默认值设置为周一<br>
     * 设置一周的第一天主要影响{@link #weekOfMonth()}和{@link #weekOfYear()} 两个方法
     *
     * @param firstDayOfWeek 一周的第一天
     * @return this
     * @see #weekOfMonth()
     * @see #weekOfYear()
     */
    @Override
    public CustomDate setFirstDayOfWeek(Week firstDayOfWeek) {
        return date(super.setFirstDayOfWeek(firstDayOfWeek));
    }

    /**
     * 设置时区
     *
     * @param timeZone 时区
     * @return this
     * @since 4.1.2
     */
    @Override
    public CustomDate setTimeZone(TimeZone timeZone) {
        return date(super.setTimeZone(timeZone));
    }

    /**
     * 明天
     **/
    public CustomDate tomorrow() {
        return this.offset(DateField.DAY_OF_YEAR, 1);
    }

    /**
    * 一天的开始
    **/
    public CustomDate begin(){
        return date(DateUtil.beginOfDay(this));
    }

    /**
    * 一天的结束
    **/
    public CustomDate end(){
        return date(DateUtil.endOfDay(this));
    }


    public CustomDate beginOfWeek(){
        return date(DateUtil.beginOfWeek(this));
    }

    public CustomDate endOfWeek(){
        return date(DateUtil.endOfWeek(this));
    }

    public CustomDate lastWeek(){
        return offset(DateField.WEEK_OF_MONTH,-1);
    }

    public CustomDate lastMonth(){
        return offset(DateField.MONTH,-1);
    }

    public CustomDate beginOfMonth(){
        return date(DateUtil.beginOfWeek(this));
    }

    public CustomDate endOfMonth(){
        return date(DateUtil.endOfMonth(this));
    }
}
